/*********************************************
 * EIRMULATOR is under the beerware license.
 *
 * THE BEERWARE LICENSE (Revision 42):
 *
 * As long as you retain this notice you can
 * do whatever you want with this stuff. If we
 * meet some day, and you think this stuff is 
 * worth it, you can buy me a drink in return.
 */


/** \file robot.h
 * \brief Definition de la classe CRobot
 * \author JDaM <brossill@enseirb.fr>
 * \version 0.8.0
 * \date 30.12.2005 @ 14:46
 *
 */

#ifndef ROBOT_H
#define ROBOT_H

#include <ode/ode.h>
#include <pthread.h>

#include <queue>

#include "configuration.h"

extern CConfiguration configuration;

using namespace std;

class CRobot
{

public:
	
  /* Enum etat du robot */
  typedef enum _ETAT_ROBOT
    {
      ER_ENJEU = 0,
      ER_HORSJEU,
      ER_ERREUR
    }ETAT_ROBOT;
	
  /* Enum couleur du robot */
	
  typedef enum _COULEUR_ROBOT 
    {
      CR_BLEU = 0,
      CR_ROUGE
    }COULEUR_ROBOT;

  typedef enum _CONTROL_MODE
    {
      CM_REMOTE = 0,
      CM_ASSERV
    }CONTROL_MODE;
	
private:
public:

  /*
    PHYSIQUE DU ROBOT
  */

  dGeomID geom;

  /*
    PARAMETRES DU ROBOT
  */

  /* *********************
     Parametres lineaires */
	
  /* Position du robot */
  dReal x;
  dReal y;
	
  /* Vitesse du robot */
  dReal v;

  /* Vitesse maximale du robot */
  dReal V_MAX;

  /* Acceleration du robot */
  dReal A;

  /* **********************
     Parametres angulaires */
	
  /* Angle du robot dans le repere direct de la table, en radians */
  dReal alpha;

  /* Vitesse angulaire du robot */
  dReal alpha_p;

  /* Vitesse angulaire MAXIMALE du robot */
  dReal ALPHA_P_MAX;
	
  /* Acceleration angulaire du robot  */
  dReal ALPHA_PP;

  /* AAA : Angle Avant Avance -> angle au dessous duquel le robot avance */
  dReal AAA;

  /* Ordres */


  /* Position précédente du robot */

  dReal last_x;
  dReal last_y;

  dReal last_alpha;
	
  /* Lors d'un deplacement vrai si le rapport a deja effectue sa premiere avance */
  bool do_first_move;

  /*
    CIBLES DU DEPLACEMENT
  */

  /* Cible en position */
  dReal cible_x;
  dReal cible_y;

  /* Cible en rotation */
  dReal cible_alpha;


  /* Remote */
  dReal remote_v;
  dReal remote_alpha_p;

  bool remote_all_stop;
  
  /*
    FLAGS DU ROBOT
  */

  /* Le robot attend de nouveaux ordres */
  bool wait;

  /* Le robot vient de se prendre un truc */
  bool collision;
	
  /* Quand il a une cible de déplacement */
  bool a_cible_position;

  /* Quand il a une cible d'angle */
  bool a_cible_angle;

  /* Le robot doit il reculer ? */
  bool recule;

  /* Distance restante à effectuer en reculant */
  dReal recule_D;
	
  /*
    CARACTERISTIQUES DU ROBOT
  */
		
  /* sa couleur */
  COULEUR_ROBOT couleur;
	
  /* son état actuel */
  ETAT_ROBOT etat;

  /* le mode de control du robot */
  CONTROL_MODE mode;
	
public:

  /* Constructeur */
  CRobot( dSpaceID,
	  dReal x, dReal y,
	  dReal alpha,
	  dReal V_MAX,
	  dReal A,
	  dReal ALPHA_P_MAX,
	  dReal ALPHA_PP,
	  dReal AAA,
	  COULEUR_ROBOT couleur,
	  ETAT_ROBOT etat,
	  CONTROL_MODE mode);

  /* Destructeur */
  ~CRobot();

  /* Accesseurs */
	
  COULEUR_ROBOT get_couleur() { return(this->couleur); };

  ETAT_ROBOT get_etat() { return(this->etat); };

  CONTROL_MODE get_mode() { return(this->mode); };

  void def_couleur(COULEUR_ROBOT couleur);

  void def_etat(ETAT_ROBOT etat);

  void def_mode(CONTROL_MODE mode);

  dReal getX() { return(this->x); };
  dReal getY() { return(this->y); };

  dReal getV() { return(this->v); };

  dReal getAlpha() { return(this->alpha); };

  dReal getAlpha_p() { return(this->alpha_p); };

  dGeomID getGeom() { return(this->geom); };

/* Flags */

  bool getflag_wait() { return(this->wait); };

  bool getflag_collision() { return(this->collision); };
	
  /* Collisions */

  void declare_collision();

  bool collisionne() { return(this->collision); };

  /* Asserv */
	
  /* Mise a jour de la position */
  void update(dReal dt);

  void update_remote(dReal dt);

  void update_asserv(dReal dt);

  void update_ODE();

  void maj_angle(dReal dt);

  void maj_position(dReal dt);

  void maj_cible_alpha();
	
  bool est_en_position();

  bool est_oriente();

  /**** Fonctions utilisateur / niveau moyen ****/

  void remote_avance();

  void remote_recule();

  void remote_gauche();

  void remote_droite();

  void remote_stop();

  /**** Fonctions utilisateur / haut niveau ****/

  /* Asservissement de la bete  */

  //void* asservi();
	
  /* Deplacement en coord relatives */

  void goto_R( dReal x, dReal y );

  void rotate_R( dReal alpha );

  void recule_R( dReal d );

  /* Deplacement en coord absolues */

  void goto_A( dReal x, dReal y );

  void rotate_A( dReal alpha );
	
};

#endif /*ROBOT_H*/
